package com.unknow.first.dapp.admin.account.utils;

import com.lianziyou.coin.price.util.CoinPriceUtil;
import com.unknow.first.dapp.admin.account.constants.ICoinTypeEnum;
import com.unknow.first.dapp.admin.account.mapper.AddressAccountInfo;
import com.unknow.first.dapp.admin.account.mapper.AddressCoinConfig;
import com.unknow.first.dapp.admin.account.service.AddressAccountInfoService;
import com.unknow.first.dapp.admin.account.service.AddressCoinConfigService;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.cloud.utils.SpringContextUtil;
import org.springframework.context.annotation.Lazy;

@Slf4j
public final class AddressAccountUtil {

    private final AddressAccountInfoService addressAccountService;
    private final AddressCoinConfigService addressCoinConfigService;

    @Lazy
    private AddressAccountUtil() {
        addressAccountService = SpringContextUtil.getBean(AddressAccountInfoService.class);
        addressCoinConfigService = SpringContextUtil.getBean(AddressCoinConfigService.class);
    }

    private final static AddressAccountUtil instance = new AddressAccountUtil();

    public static AddressAccountUtil single() {
        return instance;
    }

    public List<AddressAccountInfo> getAccountInfo(String address) {
        return getAccountInfo(address, true);
    }

    public List<AddressAccountInfo> getAccountInfo(String address, Boolean createIfNotExists) {
        List<AddressAccountInfo> addressAccountInfoList = new ArrayList<>();
        List<AddressCoinConfig> coinConfigList = addressCoinConfigService.getList(true);
        for (AddressCoinConfig addressCoinConfig : coinConfigList) {
            AddressAccountInfo accountInfo = addressAccountService.getAddressAccountByCoinId(address, addressCoinConfig.getCoinId());
            if (accountInfo == null && createIfNotExists) {
                addressAccountService.createAddressAccount(address);
                accountInfo = addressAccountService.getAddressAccountByCoinId(address, addressCoinConfig.getCoinId());
            }
            addressAccountInfoList.add(accountInfo);
        }

        addressAccountInfoList.forEach(addressAccountInfo -> {
            BigDecimal price = CoinPriceUtil.single().getUsdtPrice(addressAccountInfo.getCoinName());
            if (price != null) {
                addressAccountInfo.setUsdtValue(price.multiply(addressAccountInfo.getBalance()));
            }
        });

        return addressAccountInfoList;
    }

    public AddressAccountInfo getAccountInfo(String address, ICoinTypeEnum coinTypeEnum) {
        return getAccountInfo(address, coinTypeEnum, true);
    }

    public AddressAccountInfo getAccountInfo(String address, ICoinTypeEnum coinTypeEnum, Boolean createIfNotExists) {
        AddressAccountInfo accountInfo = addressAccountService.getAddressAccountByCoinId(address, coinTypeEnum.getId());
        if (accountInfo == null && createIfNotExists) {
            addressAccountService.createAddressAccount(address);
            accountInfo = addressAccountService.getAddressAccountByCoinId(address, coinTypeEnum.getId());
        }
        BigDecimal price = CoinPriceUtil.single().getUsdtPrice(accountInfo.getCoinName());
        if (price != null) {
            accountInfo.setUsdtValue(price.multiply(accountInfo.getBalance()));
        }
        return accountInfo;
    }
}
